<?php
/**
 * Project: AIGC
 * Author: moufer <moufer@163.com>
 * Date: 2024/7/20 10:58
 */

namespace module\chat\model;

use module\ai\model\Channel;
use module\user\model\User;
use mof\Model;
use think\db\BaseQuery;
use think\model\relation\BelongsTo;
use think\model\relation\MorphTo;

/**
 * 消息记录
 * Class Message
 * @property integer $id
 * @property integer $user_id
 * @property integer $type
 * @property integer $type_id
 * @property integer $channel_id
 * @property integer $key_id
 * @property integer $is_first
 * @property string $prompt_text
 * @property string $send_at
 * @property string $send_ip
 * @property integer $received
 * @property string $receive_text
 * @property string $receive_at
 * @property string $receive_errcode
 * @property integer send_tokens
 * @property integer receive_tokens
 * @property integer $total_tokens
 * @property User $user
 * @property Channel $channel
 * @property Unlimited|Assistant|Visrole|null $object
 */
class Message extends Model
{
    protected $name = 'chat_message';

    protected $createTime = 'send_at';
    protected $updateTime = false;

    protected $scene = [
        'prompt' => [
            'visible' => ['id', 'index', 'next_anew', 'prompt_text', 'send_at', 'channel'],
        ]
    ];

    protected array $searchFields = [
        'user_id'     => 'integer',
        'object_type' => 'string',
        'object_id'   => 'integer',
        'channel_id'  => 'integer',
        'received'    => ['integer', 'zero' => true],
        'last_id'     => 'integer'
    ];

    public static function getTypeList(): array
    {
        return [
            'unlimited' => '自由对话',
            'assistant' => '创作助手',
            'visrole'   => '虚拟助手',
        ];
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    public function channel(): BelongsTo
    {
        return $this->belongsTo(Channel::class, 'channel_id')
            ->visible(['id', 'name', 'flag']);
    }

    public function object(): MorphTo
    {
        return $this->morphTo('object', [
            'unlimited' => Unlimited::class,
            'assistant' => Assistant::class,
            'visrole'   => Visrole::class,
        ]);
    }

    /**
     * 用于下一页数据
     * @param BaseQuery $query
     * @param $value
     * @param $data
     * @return void
     */
    public function searchLastIdAttr(BaseQuery $query, $value, $data): void
    {
        if ($value > 0) $query->where('id', '<', $value);
    }

    protected function getPromptAttr($value, $data): array
    {
        //获取$data里的id,index,prompt_text,send_at
        return array_intersect_key($data, array_flip(['id', 'index', 'next_anew', 'prompt_text', 'send_at']));
    }

    protected function getReceiveAttr($value, $data): array
    {
        return [
            'content'     => $data['receive_text'],
            'status'      => empty($data['receive_errcode']) ? 'finish' : 'error',
            'received'    => $data['received'] ?? 0,
            'user_cancel' => $data['user_cancel'] ?? 0,
            'time'        => $data['receive_at'] ?? '',
            'tokens'      => [
                'send'    => $data['send_tokens'] ?? 0,
                'receive' => $data['receive_tokens'] ?? 0,
                'total'   => $data['total_tokens'] ?? 0
            ]
        ];
    }
}